﻿// ===============================================================================
// ParamNotNullOrEmpty.cs
// EOS Framework
// ===============================================================================
// Copyright (c) EOS Development Group. All rights reserved.
// ===============================================================================

namespace EOS.Framework.Tools.Aspects
{
    using System;
    using System.Diagnostics.CodeAnalysis;

    /// <summary>
    /// Combination of the <see cref="ParamNotNull"/>- and the <see cref="ParamNotEmpty"/> aspect. Verifies 
    /// if the value of a parameter with the specified name
    /// passed to the current method, where this attribute belongs to, is not null.
    /// If the passed value is a string, it also checks, if the value is not empty or if the value does
    /// not have blanks only. Can be assigned to attributes only.
    /// </summary>
    [Serializable]
    [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor, AllowMultiple=true)]
    [SuppressMessage("Microsoft.Design", "CA1019")]
    public sealed class ParamNotNullOrEmpty : ParamValidationAspect
    {       
        /// <summary>
        /// Initializes a new instance of the <see cref="ParamNotNullOrEmpty"/> class
        /// with the name of the parameter to validate.
        /// </summary>
        /// <param name="name">The name of the property to valdiate. Cannot be null (Nothing in Visual Basic)
        /// or empty or have only blanks.</param>
        /// <exception cref="ArgumentNullException"><param name="paramName"/> is null (Nothing in Visual Basic).</exception>
        /// <exception cref="ArgumentException"><paramref name="paramName"/> is a string of length 0
        /// or contains only blanks.</exception>
        public ParamNotNullOrEmpty(string name)
            : base(name)
        {
        }

        /// <summary>
        /// Called when when the value passed to the current method must be validated. The method secures 
        /// that the passed value is not null. 
        /// Throws a <see cref="ArgumentNullException"/>, if the value is not valid. If the parameter type
        /// is a string, the method assures that the passed string value is not empty or has only blanks.
        /// Throws a <see cref="ArgumentException"/>, if the value is not valid.
        /// </summary>
        /// <param name="value">The value to valide.</param>
        /// <exception cref="ArgumentNullException"><paramref name="value"/> is null 
        /// (Nothing in Visual Basic).</exception>
        /// <exception cref="ArgumentException"><paramref name="value"/> is a string
        /// and is empty or has only blanks.</exception>
        protected override void OnValidate(object value)
        {
            if (value == null)
            {
                throw new ArgumentNullException(ParamName);
            }

            string valueAsString = value as string;
            if (valueAsString != null && StringHelper.IsEmptyOrBlanksOnly(valueAsString))
            {
                throw new ArgumentException(
                    "String parameter cannot be empty and cannot contain only blanks", ParamName);
            }
        }
    }
}
